/* Copyright (c) 2022-2022, LiWangQian<liwangqian@huawei.com> All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 *    of conditions and the following disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 *    to endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <catch2/catch.hpp>
#include "libflexe/infra/stl/deque.h"
#include "libflexe/infra/stl/forward_list.h"
#include "libflexe/infra/stl/list.h"
#include "libflexe/infra/stl/map.h"
#include "libflexe/infra/stl/queue.h"
#include "libflexe/infra/stl/set.h"
#include "libflexe/infra/stl/stack.h"
#include "libflexe/infra/stl/string.h"
#include "libflexe/infra/stl/unordered_map.h"
#include "libflexe/infra/stl/unordered_set.h"
#include "libflexe/infra/stl/vector.h"

using namespace libflexe::infra::stl;

TEST_CASE("test.infra.stl.deque")
{
    auto dq = deque<int>{1,2,3,4,5};
    REQUIRE(dq.back() == 5);
    REQUIRE(dq.front() == 1);
}

TEST_CASE("test.infra.stl.forward_list")
{
    auto fl = forward_list<int>{1,2,3,4,5};
    REQUIRE(fl.front() == 1);
    fl.reverse();
    REQUIRE(fl.front() == 5);
}

TEST_CASE("test.infra.stl.list")
{
    auto l = list<int>{1,2,3,4,5};
    REQUIRE(l.front() == 1);
    REQUIRE(l.back() == 5);
}

TEST_CASE("test.infra.stl.map")
{
    auto m = map<int, const char*> {
        {1, "Hello World"},
        {2, "I Love You"},
        {3, "China"},
    };

    REQUIRE(m[1] == "Hello World");
    REQUIRE(m[2] == "I Love You");
    REQUIRE(m[3] == "China");
}

TEST_CASE("test.infra.stl.queue")
{
    auto q = queue<int>{};
    q.push(1);
    q.push(2);
    q.push(3);
    q.push(4);
    q.push(5);
    REQUIRE(q.size() == 5);
    REQUIRE(q.front() == 1);
    REQUIRE(q.back() == 5);

    auto pq = priority_queue<int>{};
    pq.push(1);
    pq.push(2);
    pq.push(5);
    pq.push(4);
    pq.push(3);
    REQUIRE(pq.top() == 5);
    REQUIRE(pq.size() == 5);
}

TEST_CASE("test.infra.stl.set")
{
    auto s = set<int>{1,2,3,4,5,5};
    REQUIRE(s.size() == 5);
    REQUIRE(s.find(1) != s.end());
    REQUIRE(s.find(5) != s.end());
}

TEST_CASE("test.infra.stl.stack")
{
    auto s = stack<int>{};
    s.push(1);
    s.push(2);
    s.push(3);
    s.push(4);
    s.push(5);
    REQUIRE(s.size() == 5);
    REQUIRE(s.top() == 5);
}

TEST_CASE("test.infra.stl.unordered_map")
{
    auto hashmap = unordered_map<const char*, const char*>{
        {"name", "uncle wang"},
        {"age", "30"},
        {"sex", "male"},
        {"adress", "Longgang, Shenzhen, China"},
    };

    REQUIRE(hashmap["name"] == "uncle wang");
    REQUIRE(hashmap["adress"] == "Longgang, Shenzhen, China");
}

TEST_CASE("test.infra.stl.unordered_set")
{
    auto countries = unordered_set<const char*>{
        "China", "Russia", "America", "Afgan", "China"
    };

    REQUIRE(countries.size() == 4);
    REQUIRE(countries.find("China") != countries.end());
}

TEST_CASE("test.infra.stl.string")
{
    string s = "I Love China!";
    REQUIRE(s[0] == 'I');
    REQUIRE(s[s.size() - 1] == '!');
}
